home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
-
- # source for log_*_msg() functions, see LP: #272301
- . /scripts/functions
-
- #
- # Standard initramfs preamble
- #
- prereqs()
- {
- # Make sure that cryptroot is run last in local-top
- for req in /scripts/local-top/*; do
- script=${req##*/}
- if [ $script != cryptroot ]; then
- echo $script
- fi
- done
- }
-
- case $1 in
- prereqs)
- prereqs
- exit 0
- ;;
- esac
-
-
- #
- # Helper functions
- #
- message()
- {
- if [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
- usplash_write "TEXT-URGENT $@"
- else
- echo "$@" >&2
- fi
- return 0
- }
-
- udev_settle()
- {
- # Wait for udev to be ready, see https://launchpad.net/bugs/85640
- if [ -x /sbin/udevadm ]; then
- /sbin/udevadm settle --timeout=30
- elif [ -x /sbin/udevsettle ]; then
- /sbin/udevsettle --timeout=30
- fi
- return 0
- }
-
- parse_options()
- {
- local cryptopts
- cryptopts="$1"
-
- if [ -z "$cryptopts" ]; then
- return 1
- fi
-
- # Defaults
- cryptcipher=aes-cbc-essiv:sha256
- cryptsize=256
- crypthash=ripemd160
- crypttarget=cryptroot
- cryptsource=""
- cryptlvm=""
- cryptkeyscript=""
- cryptkey="" # This is only used as an argument to an eventual keyscript
- crypttries=3
-
- local IFS=" ,"
- for x in $cryptopts; do
- case $x in
- hash=*)
- crypthash=${x#hash=}
- ;;
- size=*)
- cryptsize=${x#size=}
- ;;
- cipher=*)
- cryptcipher=${x#cipher=}
- ;;
- target=*)
- crypttarget=${x#target=}
- ;;
- source=*)
- cryptsource=${x#source=}
- if [ ${cryptsource#UUID=} != $cryptsource ]; then
- cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}"
- elif [ ${cryptsource#LABEL=} != $cryptsource ]; then
- cryptsource="/dev/disk/by-label/${cryptsource#LABEL=}"
- fi
- ;;
- lvm=*)
- cryptlvm=${x#lvm=}
- ;;
- keyscript=*)
- cryptkeyscript=${x#keyscript=}
- ;;
- key=*)
- if [ "${x#key=}" != "none" ]; then
- cryptkey=${x#key=}
- fi
- ;;
- tries=*)
- crypttries="${x#tries=}"
- case "$crypttries" in
- *[![:digit:].]*)
- crypttries=3
- ;;
- esac
- ;;
- esac
- done
-
- if [ -z "$cryptsource" ]; then
- message "cryptsetup: source parameter missing"
- return 1
- fi
- return 0
- }
-
- activate_vg()
- {
- local vg
- vg="${1#/dev/mapper/}"
-
- # Sanity checks
- if [ ! -x /sbin/lvm ] || [ "$vg" = "$1" ]; then
- return 1
- fi
-
- # Make sure that the device contains at least one dash
- if [ "${vg%%-*}" = "$vg" ]; then
- return 1
- fi
-
- # Split volume group from logical volume.
- vg=$(echo ${vg} | sed -e 's#\(.*\)\([^-]\)-[^-].*#\1\2#')
-
- # Reduce padded --'s to -'s
- vg=$(echo ${vg} | sed -e 's#--#-#g')
-
- lvm vgchange -ay ${vg}
- return $?
- }
-
- activate_evms()
- {
- local dev module
- dev="${1#/dev/evms/}"
-
- # Sanity checks
- if [ ! -x /sbin/evms_activate ] || [ "$dev" = "$1" ]; then
- return 1
- fi
-
- # Load modules used by evms
- for module in dm-mod linear raid0 raid1 raid10 raid5 raid6; do
- modprobe -q $module
- done
-
- # Activate it
- /sbin/evms_activate
- return $?
- }
-
- setup_mapping()
- {
- local opts count cryptcreate cryptremove NEWROOT
- opts="$1"
-
- if [ -z "$opts" ]; then
- return 0
- fi
-
- parse_options "$opts" || return 1
-
- if [ -n "$cryptkeyscript" ] && [ ! -x "$cryptkeyscript" ]; then
- message "cryptsetup: error - script \"$cryptkeyscript\" missing"
- return 1
- fi
-
- # The same target can be specified multiple times
- # e.g. root and resume lvs-on-lvm-on-crypto
- if [ -e "/dev/mapper/$crypttarget" ]; then
- return 0
- fi
-
- modprobe -q dm_crypt
-
- # Make sure the cryptsource device is available
- if [ ! -e $cryptsource ]; then
- activate_vg $cryptsource
- activate_evms $cryptsource
- fi
-
- # If the encrypted source device hasn't shown up yet, give it a
- # little while to deal with removable devices
-
- # the following lines below have been taken from
- # /usr/share/initramfs-tools/scripts/local, as suggested per
- # https://launchpad.net/bugs/164044
- if [ ! -e "$cryptsource" ]
- then
- log_begin_msg "Waiting for encrypted source device..."
-
- # Default delay is 180s
- if [ -z "${ROOTDELAY}" ]; then
- slumber=180
- else
- slumber=${ROOTDELAY}
- fi
- if [ -x /sbin/usplash_write ]; then
- /sbin/usplash_write "TIMEOUT ${slumber}" || true
- fi
-
- slumber=$(( ${slumber} * 10 ))
- while [ ! -e "$cryptsource" ]
- do
- /bin/sleep 0.1
- slumber=$(( ${slumber} - 1 ))
- [ ${slumber} -gt 0 ] || break
- done
-
- if [ ${slumber} -gt 0 ]; then
- log_end_msg 0
- else
- log_end_msg 1 || true
- fi
- if [ -x /sbin/usplash_write ]; then
- /sbin/usplash_write "TIMEOUT 15" || true
- fi
- fi
- udev_settle
-
- # We've given up, but we'll let the user fix matters if they can
- while [ ! -e "${cryptsource}" ]; do
- echo " Check cryptopts=source= bootarg cat /proc/cmdline"
- echo " or missing modules, devices: cat /proc/modules ls /dev"
- panic -r "ALERT! ${cryptsource} does not exist. Dropping to a shell!"
- done
-
- # Prepare commands
- if /sbin/cryptsetup isLuks $cryptsource > /dev/null 2>&1; then
- cryptcreate="/sbin/cryptsetup -T 1 luksOpen $cryptsource $crypttarget"
- else
- cryptcreate="/sbin/cryptsetup -T 1 -c $cryptcipher -s $cryptsize -h $crypthash create $crypttarget $cryptsource"
- fi
- cryptremove="/sbin/cryptsetup remove $crypttarget"
- NEWROOT="/dev/mapper/$crypttarget"
-
- # Try to get a satisfactory password $crypttries times
- count=0
- while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do
- count=$(( $count + 1 ))
-
- if [ $count -gt 1 ]; then
- sleep 3
- fi
-
- if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then
- message "cryptsetup: maximum number of tries exceeded for $crypttarget"
- return 1
- fi
-
- if [ -z "$cryptkeyscript" ]; then
- cryptkeyscript="/lib/cryptsetup/askpass"
- cryptkey="Unlocking the disk $cryptsource ($crypttarget)\nEnter passphrase: "
- fi
-
-
- if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
- $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=- ; then
- message "cryptsetup: cryptsetup failed, bad password or options?"
- continue
- fi
-
- if [ ! -e "$NEWROOT" ]; then
- message "cryptsetup: unknown error setting up device mapping"
- return 1
- fi
-
- FSTYPE=''
- eval $(fstype < "$NEWROOT")
-
- # See if we need to setup lvm on the crypto device
- if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then
- if [ -z "$cryptlvm" ]; then
- message "cryptsetup: lvm fs found but no lvm configured"
- return 1
- elif ! activate_vg "/dev/mapper/$cryptlvm"; then
- # disable error message, LP: #151532
- #message "cryptsetup: failed to setup lvm device"
- return 1
- fi
-
- NEWROOT="/dev/mapper/$cryptlvm"
- eval $(fstype < "$NEWROOT")
- fi
-
- if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
- message "cryptsetup: unknown fstype, bad password or options?"
- $cryptremove
- continue
- fi
-
- message "cryptsetup: $crypttarget setup successfully"
- break
- done
-
- udev_settle
- return 0
- }
-
- #
- # Begin real processing
- #
-
- # Do we have any kernel boot arguments?
- found=''
- for opt in $(cat /proc/cmdline); do
- case $opt in
- cryptopts=*)
- found=yes
- setup_mapping "${opt#cryptopts=}"
- ;;
- esac
- done
-
- if [ -n "$found" ]; then
- exit 0
- fi
-
- # Do we have any settings from the /conf/conf.d/cryptroot file?
- if [ -r /conf/conf.d/cryptroot ]; then
- while read mapping <&3; do
- setup_mapping "$mapping"
- done 3< /conf/conf.d/cryptroot
- fi
-
- exit 0
-